[fix](be) Count complex Parquet structs safely#65495
Conversation
### What problem does this PR solve?
Issue Number: N/A
Related PR: N/A
Problem Summary: Parquet COUNT pushdown used a STRUCT root repetition level to identify top-level rows when a representative leaf was repeated. Because the STRUCT repetition level is zero, all level entries were skipped and a correctness check aborted the BE. The non-null threshold also used the repeated leaf definition level and could count NULL structs. Identify top-level rows with repetition level zero and use the root nullable definition level so STRUCT columns containing ARRAY or MAP children are counted correctly.
### Release note
Fix BE aborts and incorrect COUNT results for Parquet STRUCT columns containing repeated children.
### Check List (For Author)
- Test: Unit Test
- NewParquetReaderTest targeted complex STRUCT and existing complex COUNT tests
- Behavior changed: Yes, COUNT pushdown handles repeated descendants using top-level row semantics.
- Does this need documentation: No
|
Thank you for your contribution to Apache Doris. Please clearly describe your PR:
|
|
run buildall |
|
/review |
There was a problem hiding this comment.
I reviewed the two-file Parquet COUNT pushdown change and did not find a blocking issue that needs an inline comment.
Critical checkpoint conclusions:
- Goal/test: The patch targets COUNT(col) over Parquet STRUCT columns whose representative shape leaf is under a repeated descendant. The implementation now counts top-level rows by
rep_level == 0and uses the root nullable definition level; the added BE unit test covers nullable STRUCT rows with a repeated LIST child in both child orders. - Scope: The change is small and limited to the level-counting helper plus a focused test fixture.
- Parallel paths: COUNT(*) still uses the empty-column row-count path, MIN/MAX is unchanged, and the COUNT(col) request contract still passes a top-level complex column only when exactly one directly mapped complex scan column is projected. I traced the shape-reader path through scalar/list/map/struct nested readers.
- Concurrency/lifecycle/config/persistence: No new concurrency, lifecycle ownership, config, edit-log, transaction, or persistence behavior is introduced.
- Compatibility: No Thrift, storage-format, or mixed-version protocol change is introduced.
- Error handling/data correctness: Existing status/DORIS_CHECK handling remains in place; the new comparison matches the file-reader contract that COUNT(col) should count top-level nullness.
- Performance/observability: The levels-only path still avoids value materialization for heavy nested leaves; no new observability appears necessary for this narrow fix.
- Test coverage: The new unit test is deterministic and reaches
get_aggregate_result()for the changed path. I could not run BE UTs in this runner because.worktree_initialized,thirdparty/installed, andthirdparty/installed/bin/protocare absent, so validation here was static plusgit diff --checkafter fetching the exact base commit.
User focus: No additional user-provided focus points were present.
Subagent conclusions: The optimizer-rewrite lane found no semantic-equivalence or reader row-boundary issue. The tests-session-config lane found no test/session/config/style candidate. After the final ledger update, both live subagents reviewed the same no-inline-comments ledger/comment set and replied NO_NEW_VALUABLE_FINDINGS.
BE UT Coverage ReportIncrement line coverage Increment coverage report
|
TPC-H: Total hot run time: 29280 ms |
TPC-DS: Total hot run time: 180787 ms |
ClickBench: Total hot run time: 24.99 s |
### What problem does this PR solve?
Issue Number: N/A
Related PR: N/A
Problem Summary:
Parquet COUNT pushdown uses one representative leaf to count the
top-level null state of a complex column. When a STRUCT contains an
ARRAY or MAP descendant, the representative levels are repeated. The
previous code compared repetition levels with the STRUCT root repetition
level, which is zero, skipped every level entry, and triggered a
`DORIS_CHECK` that aborted the BE. It also derived the non-null
threshold from the repeated leaf definition level and could count a NULL
struct as non-null.
This change identifies top-level rows with repetition level zero and
uses the root schema's nullable definition level to determine whether
the top-level complex value is non-null. Empty and NULL collections
inside a non-null STRUCT remain valid STRUCT rows.
### Release note
Fix BE aborts and incorrect COUNT results for Parquet STRUCT columns
containing ARRAY or MAP descendants.
### Check List (For Author)
- Test: Unit Test
-
`NewParquetReaderTest.CountStructWithRepeatedChildUsesTopLevelRowBoundaries`
- Existing STRUCT, LIST, and MAP COUNT pushdown tests
- Behavior changed: Yes. COUNT pushdown uses top-level row/null
semantics for repeated descendants.
- Does this need documentation: No
Validation on the designated Linux build host:
- `build-support/check-format.sh`
- Targeted BE unit tests: 4 tests passed
- `run-clang-tidy.sh`: test file has no warnings; production analysis
reports pre-existing full-file diagnostics and `jni-util.h` toolchain
static assertions unrelated to this change.
## Summary Backport the FileScannerV2 / format_v2 series to `branch-4.1` in the requested order. - Includes 28 unique source PRs, including #65502. - FileScannerV2 and format_v2 use their native implementations. - #62306 is intentionally not cherry-picked. FileScannerV2 and format_v2 do not depend on it; the V1 behavior required by this series is adapted manually on top of the existing branch-4.1 code. - The V1 adaptations cover TopN validation, deletion-vector handling, runtime-filter cloning/type semantics, JNI cleanup retry, Paimon IOManager/metrics, text-reader fixes, and the branch-4.1 expression API used by equality-delete predicates. - Native format_v2 JDBC and Iceberg system-table paths remain on the branch-4.1 legacy/unsupported routing because the newer thrift split protocols are not present on this branch. ## Source PRs #65046, #65130, #65151, #65175, #65194, #65218, #65281, #65326, #65328, #65332, #65354, #65094, #65351, #65359, #65370, #65183, #65369, #65449, #65437, #65451, #65475, #65495, #65496, #65501, #65500, #65478, #65503, #65502. ## Branch-specific fixes - Adapted #65502 to the branch-4.1 expression selector API and fixed the associated FE checkstyle issues. - Fixed TeamCity External Regression 994576 and P0/CloudP0 995015/995017: schema discovery does not create a `RuntimeState`, so V1 CSV, JSON, Native, ORC, and Parquet readers now fall back to default `TQueryOptions` instead of dereferencing a null state. - Fixed TeamCity BE UT 994856, which crashed in the same V1 ORC reader-options path. - Restored only the small V1 schema-reader fallback required on branch-4.1; #62306 remains intentionally excluded. - Added null-`RuntimeState` regression coverage for CSV and Native schema discovery. - Initialized the format_v2 ORC test suite timezone cache once at suite setup, covering session-timezone and DST timestamp assertions that become reachable after the V1 ORC core is fixed. ## Validation - Full ASAN `doris_be_test` build compiled and linked successfully; the post-#65502 incremental verification completed 1,091/1,091 build targets. - 313/313 focused BE tests passed across FileScannerV2, TableReader, ColumnMapper, condition cache, deletion vectors/predicates, JNI, Hive/Paimon/Iceberg readers, zonemap filtering, and casts. - The latest ASAN verification passed 232/232 focused Iceberg reader, equality-delete, ColumnMapper, and TableReader tests. - 215/215 affected reader tests passed across V1 CSV/JSON/Native/ORC/Parquet and format_v2 ORC/Parquet, including the TeamCity ORC core reproducer. - The three format_v2 ORC session-timezone assertions passed 3/3 under ASAN. - 88/88 original focused FE tests passed; the post-#65502 FE verification passed an additional 40/40 tests covering ExternalUtil and Iceberg planning/utilities. - 10/10 `PaimonJniScannerTest` tests passed. - Maven reactor completed with `BUILD SUCCESS`; checkstyle reported 0 violations. - `build-support/check-format.sh` passed across 4,136 files. --------- Co-authored-by: Chenjunwei <138805230+xylaaaaa@users.noreply.github.com>
What problem does this PR solve?
Issue Number: N/A
Related PR: N/A
Problem Summary:
Parquet COUNT pushdown uses one representative leaf to count the top-level null state of a complex column. When a STRUCT contains an ARRAY or MAP descendant, the representative levels are repeated. The previous code compared repetition levels with the STRUCT root repetition level, which is zero, skipped every level entry, and triggered a
DORIS_CHECKthat aborted the BE. It also derived the non-null threshold from the repeated leaf definition level and could count a NULL struct as non-null.This change identifies top-level rows with repetition level zero and uses the root schema's nullable definition level to determine whether the top-level complex value is non-null. Empty and NULL collections inside a non-null STRUCT remain valid STRUCT rows.
Release note
Fix BE aborts and incorrect COUNT results for Parquet STRUCT columns containing ARRAY or MAP descendants.
Check List (For Author)
NewParquetReaderTest.CountStructWithRepeatedChildUsesTopLevelRowBoundariesValidation on the designated Linux build host:
build-support/check-format.shrun-clang-tidy.sh: test file has no warnings; production analysis reports pre-existing full-file diagnostics andjni-util.htoolchain static assertions unrelated to this change.